#ifndef __NET_MESSAGE_PARSE_H__
#define __NET_MESSAGE_PARSE_H__

#include <boost/asio.hpp>

#define MSG_HEAD_LEN 10

union MessageID
{
    struct stMessageID
    {
        uint16_t moduleType;
        uint16_t msgID;
        uint16_t encrypType;
        uint16_t resver;

    stMessageID(uint16_t _moduleType, uint16_t _msgID, uint16_t _encrypType, uint16_t _resver)
        : moduleType(_moduleType)
        , msgID(_msgID)
        , encrypType(_encrypType)
        , resver(_resver)  {}

    } stMsg;

    uint64_t msgID;

    MessageID(uint16_t _moduleType, uint16_t _msgID, uint16_t _encrypType, uint16_t _resver)
    : stMsg(_moduleType, _msgID, _encrypType, _resver) {}

    MessageID(uint16_t _moduleType, uint16_t _msgID) : MessageID (_moduleType, _msgID, 0, 0) {}

    MessageID(uint64_t id) : msgID(0) { msgID = id; }
};

enum ParseResultState
{
    eFailed = 0,
    eSuc = 1,
    eNeedMore = 2,
};


class MessageParse
{
public:
    enum State
    {
        eInit,
        eParseTag,
        eParseHeader,
        eParseData,
    };

    struct MessageHeader
    {
        MessageID msgID;
        int16_t bufLen;

    MessageHeader() : msgID(0), bufLen(0) {}
    };

    MessageParse();

    boost::asio::streambuf::mutable_buffers_type getMutableBufs();

    boost::asio::streambuf& getConstBufs() { return bufs_; }

    const MessageHeader& getMsgHeader() const { return msgHeader_; }

    ParseResultState parse(std::size_t bytes_transferred);
private:
    boost::asio::streambuf bufs_;
    State state_;  // parse state
    MessageHeader msgHeader_;
};


#endif // __NET_MESSAGE_PARSE_H__
